<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

class Dbsync_mysql extends Dbsync_driver
{
	/**
	 * Read the MySQL DB Schema and return a standard DBSync schema object
	 *
	 * @return object
	 */
	public function read_db_schema()
	{
		//Setup some variables we will need
		$db_prefix = $this->db->dbprefix;

		$db_tablelist = $this->db->list_tables();

		$table_array = array();
		foreach($db_tablelist as $curr_table)
		{
			$curr_table_name = $curr_table;
			$curr_table_fields = $this->db->query("DESCRIBE " . $curr_table . ";");

			if (is_object($curr_table_fields) && method_exists($curr_table_fields, 'result'))
				$curr_table_fields = $curr_table_fields->result();
			else
				$curr_table_fields = array();

			foreach($curr_table_fields as $curr_field)
			{
				$type_const_signed = strtolower($curr_field->Type);

				$obj = (object) NULL;

				//zerofill
				if (strpos($type_const_signed, 'zerofill') !== FALSE)
				{
					$obj->zerofill = 'true';
					$type_const_signed = trim(str_replace("zerofill", '', $type_const_signed));
				}

				//unsigned
				if (strpos($type_const_signed, 'unsigned') !== FALSE)
				{
					$obj->unsigned = 'true';
					$type_const_signed = trim(str_replace("unsigned", '', $type_const_signed));
				}

				//constraint
				if (strpos($type_const_signed, '(') !== FALSE)
				{
					$obj->constraint = trim(substr(str_replace(")", '', trim($type_const_signed)), strpos($type_const_signed, '(')+1));
					$type_const_signed = trim(substr($type_const_signed, 0, strpos($type_const_signed, '(')));
				}
				else
					$obj->constraint = '';

				//type is all that's left
				$obj->type = $type_const_signed;

				//default
				if (isset($curr_field->Default) && $curr_field->Default != NULL)
					$obj->default = $curr_field->Default;

				//primary_key
				if (isset($curr_field->Key) && strtoupper($curr_field->Key) == 'PRI')
					$obj->primary_key = 'true';

				//null (that's right.. default to TRUE)
				if (isset($curr_field->Null) && strtoupper($curr_field->Null) == "NO")
					$obj->null = 'false';
				else
					$obj->null = 'true';

				//auto_increment
				if (isset($curr_field->Extra) && strpos(strtolower($curr_field->Extra), 'auto_increment') !== FALSE)
					$obj->auto_increment = 'true';

				$table_array[$curr_table_name]->fields[$curr_field->Field] = $obj;
				unset($obj);
			}
		}

		//Return it!  w00t
		$out_obj = (object) NULL;
		$out_obj->tables = $table_array;
		return $out_obj;
	}
	
	// --------------------------------------------------------------------

	/**
	 * Generate a MySQL drop table query
	 *
	 * @param string $table_name
	 * @return string
	 */
	public function generate_db_drop_query($table_name)
	{
		return "DROP TABLE $table_name;";
	}

	// --------------------------------------------------------------------

	/**
	 * Generate a MySQL create table query
	 *
	 * @param string $table_name
	 * @param object $table_data
	 * @return string
	 */
	public function generate_db_create_query($table_name, $table_data)
	{
		$field_data = $table_data->fields;
		
		$sql_query = "CREATE TABLE $table_name (";

		$fields = array();
		foreach($field_data as $field_name => $obj)
		{
			$query = "$field_name $obj->type";

			if (isset($obj->constraint))
				$query .= "($obj->constraint)";
			if (isset($obj->unsigned) && $obj->unsigned == 'true')
				$query .= " unsigned";
			if (isset($obj->zerofill) && $obj->zerofill == 'true')
				$query .= " zerofill";
			if (isset($obj->null) && $obj->null == 'false')
				$query .= " NOT NULL";
			if (isset($obj->primary_key) && $obj->primary_key == 'true')
					$query .= " PRIMARY KEY";
			if (isset($obj->auto_increment) && $obj->auto_increment == 'true')
					$query .= " AUTO_INCREMENT";
			if (isset($obj->default))
					$query .= " DEFAULT '$obj->default'";

			$fields[] = $query;
		}

		$sql_query .= implode(", ", $fields);
		$sql_query .= ");";

		return $sql_query;
	}

	// --------------------------------------------------------------------

	/**
	 * Generate a MySQL ALTER TABLE query
	 *
	 * @param string $table_name
	 * @param string $field_action (update, add, or remove only)
	 * @param string $field_name
	 * @param object $field_attrs
	 * @return string
	 */
	public function generate_db_alter_query($table_name, $field_action, $field_name, $field_attrs)
	{
		if ($field_action == 'update')
		{
						$obj = $field_attrs;
						$query = "ALTER TABLE $table_name MODIFY `$field_name` $obj->type";
		}
		elseif ($field_action == 'add')
		{
						$obj = $field_attrs;
						$query = "ALTER TABLE $table_name ADD `$field_name` $obj->type";
		}
		elseif ($field_action == 'remove')
		{
			return "ALTER TABLE $table_name DROP COLUMN  $field_name;";
		}
		else
			user_error("Cannot run generate_db_alter_query for MySQL table $table_name.  The field_action must be 'add', 'remove', or 'update'.  You sent: $field_action.", E_USER_ERROR);

		//If it was an add or modify query.. fill in the rest of the details here....
		//
		if (isset($obj->constraint))
						$query .= "($obj->constraint)";
		if (isset($obj->unsigned) && $obj->unsigned == 'true')
						$query .= " unsigned";
		if (isset($obj->zerofill) && $obj->zerofill == 'true')
						$query .= " zerofill";
		if (isset($obj->null) && $obj->null == 'false')
						$query .= " NOT NULL";
		if (isset($obj->auto_increment) && $obj->auto_increment == 'true')
						$query .= " AUTO_INCREMENT";
		if (isset($obj->default) && $obj->default != '')
						$query .= " DEFAULT '$obj->default'";
						
		$query .= ";";
		return $query;

	}

	// --------------------------------------------------------------------

	/**
	 * Generate a MySQL INSERT record query
	 *
	 * @param string $table_name
	 * @param object $new_record_obj
	 * @return string
	 */
	public function generate_db_insert_query($table_name, $new_record_obj)
	{
		$new_record = (array) $new_record_obj;

		$sql_code = "INSERT INTO `$table_name` (`" . implode('`, `', array_keys($new_record)) . "`) VALUES ('" . implode("', '", $new_record) . "');";
		
		return $sql_code;
	}

	// --------------------------------------------------------------------

	/**
	 * Returns the last error from the MySQL database server
	 *
	 * @todo Test this Function!
	 * @return string
	 */
	public function get_db_error()
	{
		return $this->db->call_function('mysql_error');
	}
}

/* End of file dbsync_mysql.php */
/* Location: ./app/libraries/Dbsync_drivers/dbsync_mysql.php */